package com.alibaba.user.service.impl;

import com.alibaba.basic.dto.SendEmailCodeDto;
import com.alibaba.basic.service.impl.BaseServiceImpl;
import com.alibaba.basic.uitl.BusinessException;
import com.alibaba.basic.uitl.StrUtils;
import com.alibaba.user.domain.Logininfo;
import com.alibaba.user.domain.User;
import com.alibaba.user.mapper.LogininfoMapper;
import com.alibaba.user.mapper.UserMapper;
import com.alibaba.user.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author itsource
 * @since 2023-03-04
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Override
    public void emailRegister(SendEmailCodeDto dto) {
        // 校验参数
        if (StringUtils.isBlank(dto.getPassword()) || StringUtils.isBlank(dto.getPasswordRepeat())){
            throw  new BusinessException("密码不能为空");
        }
        // 判断两次密码是否一致
        if (!dto.getPassword().equals(dto.getPasswordRepeat())){
            throw new BusinessException("两次密码不一样");
        }
        // 判断验证码是否正常
        String uuidEmail = (String) redisTemplate.opsForValue().get(dto.getEmailCodeUUID());
        if (!uuidEmail.equals(dto.getEmailCode())){
            throw new BusinessException("验证码错误");
        }
        // 判断邮箱是否注册过
        User byEmail = userMapper.findByEmail(dto.getEmail());
        if (byEmail != null){
            throw new BusinessException("滚去登录");
        }
        // 4.保存数据 先 logininfo 再user

        // 添加logininfo表
        Logininfo logininfo = new Logininfo();
        // 名字默认是邮箱
        logininfo.setUsername(dto.getEmail());
        // 邮箱存邮箱
        logininfo.setEmail(dto.getEmail());
        // 生成随机数盐值
        String salt = StrUtils.getComplexRandomString(32);
        logininfo.setSalt(salt);
        logininfo.setPassword(salt+dto.getPassword());
        logininfoMapper.add(logininfo);

        // 添加User
        User user = new User();
        BeanUtils.copyProperties(logininfo,user);
        user.setLogininfoId(logininfo.getId());
        userMapper.add(user);

    }

    @Override
    public User findByLogininfoId(Long logininfoId) {

        return userMapper.findByLogininfoId(logininfoId);
    }

   /* @Override
    public AjaxResult account(AccountDto dto) {
        // 校验参数
        // 2.根据账号查询logininfo表数据 邮箱、手机、username都可以作为账号登录
        Logininfo logininfo = logininfoMapper.finByAccount(dto);
        if (logininfo == null){
            throw new BusinessException("账号或密码错误");
        }
        // 3.密码是否正常
        *//**
         * 1.把前端传过来的密码先接收
         * 2.因为我们数据库的密码是加密的，而前端传过来的密码没有加密，所有我们需要做加密
         * 3.在把我们数据的密码拿出来进行比较
         * 4.为了严谨，我们可以进行一下非空判断
         *//*
        String passPima = dto.getPassword();
        String passMd5 = MD5Utils.encrypByMd5(logininfo.getSalt() + passPima);
        String passwordDb = logininfo.getPassword();
        if (StringUtils.isBlank(passMd5) || StringUtils.isBlank(passwordDb) || !passMd5.equals(passwordDb)){
            throw new BusinessException("账号或密码错误");
        }

        // 4.登录成功后给前端返回数据
        *//**
         * 1.我们可以使用UUID作为token，保证每个用户的登录凭证唯一 UUID.randomUUID().toString();
         * 2.设置一个保存时间
         * 3.返还给前端数据、
         * 4.返回数据之前 将logininfo中敏感数据 置空
         * 5.用一个map保存
         * 6.生成token 存入到redis
         *//*
        Map<String, Object> map = getMap(logininfo);
        return AjaxResult.me().success(map);
    }

    private Map<String, Object> getMap(Logininfo logininfo) {
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);
        logininfo.setPhone(null);
        logininfo.setEmail(null);
        logininfo.setPassword(null);
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("logininfo", logininfo);
        return map;
    }*/


    // 登录
   /* @Override
    public AjaxResult account(AccountDto dto) {
        // 1.检验参数
        // 2.根据账号查询logininfo表数据 邮箱、手机、username都可以作为账号登录
        Logininfo logininfo = logininfoMapper.finByAccount(dto);
        if (null == logininfo){
            throw new BusinessException("账号或密码错误1");
        }
        // 3.密码是否正常
        String passParam = dto.getPassword(); // 前端传来的密码
        String passMd5 = MD5Utils.encrypByMd5(logininfo.getSalt() + passParam);
        String passwordDb = logininfo.getPassword();
        if (StringUtils.isBlank(passwordDb) || StringUtils.isBlank(passMd5) || !passMd5.equals(passwordDb)){
            throw new BusinessException("账号或密码错误");
        }
        // 4.登录成功后返还给前端数据
        // 生成token 存入到redis
        Map<String, Object> map = getMap(logininfo);
        return AjaxResult.me().success(map);
    }

    private Map<String, Object> getMap(Logininfo logininfo) {
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);
        // 将数据返回给前端
        // 返回数据之前 将logininfo中敏感数据 置空
        logininfo.setPassword(null);
        logininfo.setPhone(null);
        logininfo.setEmail(null);
        Map<String, Object> map = new HashMap<>();
        map.put("token",token);
        map.put("logininfo", logininfo);
        return map;
    }*/



}
